home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / programming / ixemul-complete / ixemul / library / ix_open.c < prev    next >
C/C++ Source or Header  |  1996-08-13  |  8KB  |  229 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *  Portions Copyright (C) 1994 Rafael W. Luebbert
  5.  *  Portions Copyright (C) 1995 Jeff Shepherd
  6.  *
  7.  *  This library is free software; you can redistribute it and/or
  8.  *  modify it under the terms of the GNU Library General Public
  9.  *  License as published by the Free Software Foundation; either
  10.  *  version 2 of the License, or (at your option) any later version.
  11.  *
  12.  *  This library is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  *  Library General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU Library General Public
  18.  *  License along with this library; if not, write to the Free
  19.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  */
  21.  
  22. #define _KERNEL
  23. #include "ixemul.h"
  24. #include "kprintf.h"
  25.  
  26. #include <hardware/intbits.h>
  27. #include <exec/memory.h>
  28. #include <string.h>
  29.  
  30. extern void launch_glue (), switch_glue ();
  31. extern void trap_20 ();
  32. extern void trap_00 ();
  33. extern int ix_timer();
  34.  
  35. static BOOL
  36. __ix_open_muFS (struct user *ix_u)
  37. {
  38.   if (muBase)
  39.     {
  40.       /* set up multiuser data's */
  41.       ix_u->u_UserInfo = muAllocUserInfo ();
  42.       if (NULL == ix_u->u_UserInfo)
  43.         return FALSE;
  44.       ix_u->u_fileUserInfo = muAllocUserInfo ();
  45.       if (NULL == ix_u->u_fileUserInfo)
  46.         return FALSE;
  47.  
  48.       ix_u->u_GroupInfo = muAllocGroupInfo ();
  49.       if (NULL == ix_u->u_GroupInfo)
  50.         return FALSE;
  51.       ix_u->u_fileGroupInfo = muAllocGroupInfo ();
  52.       if (NULL == ix_u->u_fileGroupInfo)
  53.         return FALSE;
  54.     }
  55.   return TRUE;
  56. }
  57.  
  58. struct ixemul_base *
  59. ix_open (struct ixemul_base *ixbase)
  60. {
  61.   /* here we must initialize our `user' structure */
  62.   struct user *ix_u;
  63.   /* an errno for those that later don't set it in ix_startup() */
  64.   static int default_errno;
  65.   /* an h_errno for those that later don't set it in ix_startup() */
  66.   static int default_h_errno;
  67.   struct Task *me;
  68.   char *tmp;
  69.   int a4_size = A4_POINTERS * 4;
  70.  
  71.   me = SysBase->ThisTask;
  72.  
  73.   tmp = (char *)kmalloc(sizeof(struct user) + a4_size);
  74.   if (tmp)  
  75.     {
  76.       /* bzero is safe, ie. doesn't need to reference struct user */
  77.       bzero (tmp, sizeof (struct user) + a4_size);
  78.       ix_u = (struct user *)(tmp + a4_size);
  79.  
  80.       /* remember old state */
  81.       ix_u->u_otask_flags = me->tc_Flags;
  82.       ix_u->u_olaunch     = me->tc_Launch;
  83.       ix_u->u_oswitch     = me->tc_Switch;
  84.       ix_u->u_otrap_code  = me->tc_TrapCode;
  85.       ix_u->u_otrap_data  = me->tc_TrapData;
  86.     
  87.       NewList ((struct List *) &ix_u->u_md.md_list);
  88.  
  89.       ix_u->u_mdp           = &ix_u->u_md;
  90.  
  91.       KPRINTF (("ix_open: ix_u = $%lx, ix_open @$lx\n", ix_u, ix_open));
  92.  
  93.       me->tc_TrapData  = (APTR)ix_u;
  94.  
  95.       if (betterthan68000())
  96.     me->tc_TrapCode = trap_20;
  97.       else
  98.     me->tc_TrapCode = trap_00;
  99.  
  100.       initstack();
  101.  
  102.       /* setup the p_sigignore mask correctly */
  103.       siginit (ix_u);
  104.       me->tc_SigRecvd &= 0x0fff;
  105.  
  106.       /* this library is a replacement for any c-library, thus we should be
  107.        * started at the START of a program, and out of 16 available signals 
  108.        * these calls simply have to succeed... I know I'm a lazy guy ;-) */
  109.       ix_u->u_sleep_sig = AllocSignal (-1);
  110.       ix_u->u_pipe_sig = AllocSignal (-1);
  111.  
  112.       ix_u->u_ixbase = ixbase;
  113.       ix_u->u_errno = &default_errno;
  114.       ix_u->u_h_errno = &default_h_errno;
  115.  
  116.       /* ixnet.library is loaded iff ixbase->ix_network_type != IX_NETWORK_NONE */
  117.       if (ixbase->ix_network_type != IX_NETWORK_NONE)
  118.     ix_u->u_ixnetbase = OpenLibrary("ixnet.library", ix.ix_lib.lib_Version);
  119.  
  120.       me->tc_Launch    = launch_glue;
  121.       me->tc_Switch    = switch_glue;
  122.       me->tc_Flags    |= TF_LAUNCH | TF_SWITCH;
  123.       ix_u->u_itimerint.is_Node.ln_Type = NT_INTERRUPT;
  124.       ix_u->u_itimerint.is_Node.ln_Name = me->tc_Node.ln_Name;
  125.       ix_u->u_itimerint.is_Node.ln_Pri  = 1;
  126.       ix_u->u_itimerint.is_Data         = (APTR) me;
  127.       ix_u->u_itimerint.is_Code            = (APTR) ix_timer;
  128.  
  129.  
  130.       AddIntServer (INTB_VERTB, &ix_u->u_itimerint);
  131.  
  132.       ix_u->u_trace_flags = 1;
  133.       ix_u->u_sync_mp = (struct MsgPort *) syscall (SYS_CreatePort, 0, 0);
  134.       ix_u->u_select_mp = (struct MsgPort *) syscall (SYS_CreatePort, 0, 0);
  135.       
  136.       /* the CD storage. since 0 is a valid value for a lock, we use -1 */
  137.       ix_u->u_startup_cd = (BPTR)-1;
  138.  
  139.       /* support for subprocesses a la Unix */
  140.  
  141.       /* each process starts out to be in its own process group. vfork()
  142.        * scribbles over this to inherit the parents process group instead */
  143.       ix_u->p_pgrp = (int) me;
  144.       ix_u->p_pptr = (struct Process *) 1;        /* hi init ;-)) */
  145.       ix_u->p_cptr =
  146.         ix_u->p_osptr =
  147.           ix_u->p_ysptr = 0;            /* no children to start with */
  148.       ix_u->p_vfork_msg = 0;
  149.       ix_u->p_zombie_sig = AllocSignal (-1);
  150.       ix_u->u_rand_next = 1;
  151.       NewList ((struct List *) &ix_u->p_zombies);
  152.       strcpy(ix_u->u_logname, "unknown");
  153.       ix_u->u_LogFile = -1;
  154.       ix_u->u_LogTag = "syslog";
  155.       ix_u->u_LogFacility = LOG_USER;
  156.       ix_u->u_LogMask = 0xff;
  157.       ix_u->u_a4_pointers_size = A4_POINTERS;
  158.  
  159.       if (ix_u->u_sync_mp && ix_u->u_select_mp)
  160.         {
  161.           ix_u->u_time_req = (struct timerequest *)
  162.         syscall (SYS_CreateExtIO, ix_u->u_sync_mp, sizeof (struct timerequest));
  163.       
  164.       if (ix_u->u_time_req)
  165.         {
  166.           if (!OpenDevice (TIMERNAME, UNIT_MICROHZ,
  167.                          (struct IORequest *) ix_u->u_time_req, 0))
  168.             {
  169.           syscall (SYS_gettimeofday, &ix_u->u_start, 0);
  170.  
  171.           /* have to mask out ALL signals until ix_startup has had a
  172.            * chance to setup its exit jmp_buf. If not, _longjmp will
  173.            * generate a longjmp-botch using a not initialized jmpbuf! */
  174.           syscall (SYS_sigsetmask, ~0);
  175.  
  176.           /* if enabled, set the red zone pointer for stack watch */
  177.           if (ixbase->ix_red_zone_size)
  178.             {
  179.               struct Process *mep = (struct Process *) me;
  180.               struct CommandLineInterface *CLI = BTOCPTR (mep->pr_CLI);
  181.               u_int stack_size = CLI ? CLI->cli_DefaultStack * 4 : mep->pr_StackSize;
  182.  
  183.               /* I guess the above approach to find the correct stack
  184.                  size will work most of the time. But using tc_Lower
  185.                  as lower bound would probably not work. Thus I'm using
  186.                  the current stack value, not the unknown `real' top stack
  187.              as top and subtract the stack_size to get to the bottom */
  188.  
  189.               if (stack_size > ixbase->ix_red_zone_size)
  190.                 ix_u->u_red_zone = (void *)(get_sp () - stack_size 
  191.                              + ixbase->ix_red_zone_size);
  192.             }
  193.                   if (__ix_open_muFS (ix_u))
  194.             return ixbase;
  195.                   else
  196.                     {
  197.                       /* couldn't allocate muFS stuff */
  198.                       __ix_close_muFS (ix_u);
  199.                     }
  200.         }
  201.           /* couldn't open the timer device */
  202.           syscall (SYS_DeleteExtIO, ix_u->u_time_req);
  203.         }
  204.         }
  205.  
  206.       if (ix_u->u_select_mp)
  207.         syscall (SYS_DeletePort, ix_u->u_select_mp);
  208.  
  209.       if (ix_u->u_sync_mp)
  210.         syscall (SYS_DeletePort, ix_u->u_sync_mp);
  211.  
  212.       RemIntServer (INTB_VERTB, &ix_u->u_itimerint);
  213.       me->tc_Flags    = ix_u->u_otask_flags;
  214.       me->tc_Launch   = ix_u->u_olaunch;
  215.       FreeSignal (ix_u->u_sleep_sig);
  216.       FreeSignal (ix_u->u_pipe_sig);
  217.       FreeSignal (ix_u->p_zombie_sig);
  218.  
  219.       /* all_free() MUST come before we remove the pointer to u */
  220.       all_free ();
  221.       me->tc_TrapCode = ix_u->u_otrap_code;
  222.       me->tc_TrapData = ix_u->u_otrap_data;
  223.  
  224.       kfree (tmp);
  225.     }
  226.  
  227.   return 0;
  228. }
  229.